/**
 * 宝石镶嵌1092指令测试脚本
 * 基于test-code-1336.js修改
 * 专注于测试：宝石背包查询(6034) → 1090查询可镶嵌装备 → 1092宝石镶嵌逻辑
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
    server: {
        host: 'localhost',
        port: 3000,
        protocol: 'http'
    },
    testUser: {
        mobile: '17091271111',
        password: '123456',
        passwordHash: 'e10adc3949ba59abbe56e057f20f883e'
    },
    testCharacter: {
        name: '测试角色',
        sex: 1,
        roleType: 1,
        headIndex: 2
    }
};

class GemSocket1092Tester {
    constructor() {
        this.token = null;
        this.userId = null;
        this.ws = null;
        this.characters = [];
        this.selectedCharacter = null;
        this.testResults = [];
        this.gemInventory = [];
        this.socketableEquipments = [];
        this.socketResults = [];
    }

    async runTest() {
        console.log('💎 开始宝石镶嵌1092指令测试...\n');
        console.log('测试目标：HTTP登录 → WebSocket连接 → 选择角色 → 查询宝石背包 → 测试1090/1092指令逻辑\n');

        try {
            await this.testHttpLogin();
            await this.testWebSocketConnection();
            await this.testQueryCharacters();

            if (this.characters.length === 0) {
                await this.testCreateCharacter();
                await this.testQueryCharacters();
            }

            await this.testSelectCharacter();
            await this.testQueryGemInventory();
            await this.testGemSocketLogic();
            await this.testDisconnect();
            this.printTestResults();
        } catch (error) {
            console.error('❌ 测试过程中发生错误:', error.message);
            this.addTestResult('整体测试', false, error.message);
        }
    }

    async testHttpLogin() {
        console.log('🔐 步骤1: HTTP登录测试...');
        try {
            await this.registerUser();
            const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });

            if (loginData.code === 0 && loginData.data) {
                this.userId = loginData.data.userId;
                this.token = loginData.data.accessToken;
                console.log(`✅ 登录成功: userId=${this.userId}`);
                this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);
            } else {
                throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
            }
        } catch (error) {
            console.log('❌ 登录失败:', error.message);
            this.addTestResult('HTTP登录', false, error.message);
            throw error;
        }
    }

    async registerUser() {
        try {
            const res = await this.makeHttpRequest('/user-service/user/register', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash,
                captcha: '123456'
            });
            console.log('📝 用户注册成功', res);
        } catch (error) {
            if (error.message.includes('MOBILE_EXISTS') || error.message.includes('已存在')) {
                console.log('👤 用户已存在，跳过注册');
            } else {
                console.log('⚠️ 注册失败:', error.message);
            }
        }
    }

    async testWebSocketConnection() {
        console.log('\n🔌 步骤2: WebSocket连接测试...');
        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
                this.ws = new WebSocket(wsUrl);

                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');
                    this.addTestResult('WebSocket连接', true, '连接建立成功');
                    this.setupMessageHandler();
                    await this.delay(500);
                    resolve();
                });

                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    this.addTestResult('WebSocket连接', false, error.message);
                    reject(error);
                });

                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });

                setTimeout(() => {
                    if (this.ws.readyState === WebSocket.CONNECTING) {
                        this.ws.close();
                        reject(new Error('连接超时'));
                    }
                }, 10000);
            } catch (error) {
                reject(error);
            }
        });
    }

    setupMessageHandler() {
        this.ws.on('message', (data) => {
            try {
                const message = JSON.parse(data.toString());
                console.log('📨 收到消息:', JSON.stringify(message, null, 2));
                this.handleWebSocketResponse(message);
            } catch (error) {
                console.error('❌ 消息解析失败:', error.message);
            }
        });
    }

    handleWebSocketResponse(message) {
        const { act_id, code, roleList, roleCount, data, msg, list } = message;

        switch (act_id) {
            case 3:
                if (roleList && Array.isArray(roleList)) {
                    this.characters = roleList;
                    console.log(`📋 获取到${roleCount || roleList.length}个角色`);
                }
                break;
            case 4:
                if (code === 0) {
                    console.log('🎯 角色选择成功');
                }
                break;
            case 5:
            case 390:
                if (code === 0) {
                    console.log('🆕 角色创建成功');
                }
                break;
            case 6034:
                if (code === 0 && list) {
                    this.gemInventory = list;
                    console.log(`💎 宝石背包查询成功，获取${list.length}个宝石`);
                }
                break;
            case 1090:
                if (code === 0 && data) {
                    this.socketableEquipments = data;
                    console.log(`🔧 可镶嵌装备查询成功，获取${data.length}件装备`);
                }
                break;
            case 1092:
                this.socketResults.push({
                    act_id: message.act_id,
                    code: message.code,
                    msg: message.msg,
                    data: message.data,
                    timestamp: new Date().toISOString()
                });
                console.log(`⚡ 宝石镶嵌结果:`, JSON.stringify(message, null, 2));
                break;
        }
    }

    async testQueryCharacters() {
        console.log('\n📋 步骤3: 查询角色列表...');
        return new Promise(async (resolve) => {
            if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
                this.addTestResult('查询角色列表', false, 'WebSocket未连接');
                resolve();
                return;
            }

            await this.delay(1000);

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 3) {
                        this.ws.removeListener('message', responseHandler);

                        if (message.roleList && Array.isArray(message.roleList)) {
                            this.characters = message.roleList;
                            console.log(`✅ 查询成功，共${message.roleCount || message.roleList.length}个角色`);
                            this.addTestResult('查询角色列表', true, `获取${this.characters.length}个角色`);
                        } else {
                            this.characters = [];
                            console.log('✅ 查询成功，暂无角色');
                            this.addTestResult('查询角色列表', true, '获取0个角色');
                        }
                        resolve();
                    }
                } catch (error) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('查询角色列表', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 3, d: null }));

            setTimeout(() => {
                this.ws.removeListener('message', responseHandler);
                this.addTestResult('查询角色列表', false, '请求超时');
                resolve();
            }, 10000);
        });
    }

    async testCreateCharacter() {
        console.log('\n🆕 步骤4: 创建角色测试...');
        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('创建角色', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;
            let retryCount = 0;
            const maxRetries = 2;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 5 || message.act_id === 390) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0) {
                            console.log('✅ 角色创建成功');
                            this.addTestResult('创建角色', true, '角色创建成功');
                            setTimeout(() => resolve(), 2000);
                        } else {
                            const errorMsg = message.msg || '未知错误';
                            console.log(`❌ 角色创建失败: ${errorMsg}`);

                            if (errorMsg.includes('重复') || errorMsg.includes('已存在') || errorMsg.includes('DUPLICATE')) {
                                if (retryCount < maxRetries) {
                                    retryCount++;
                                    const newName = `${CONFIG.testCharacter.name}_${Date.now()}`;
                                    console.log(`🔄 角色名重复，尝试使用新名字: ${newName}`);
                                    setTimeout(() => {
                                        this.createCharacterWithName(newName, resolve);
                                    }, 1000);
                                    return;
                                }
                            }

                            this.addTestResult('创建角色', false, errorMsg);
                            resolve();
                        }
                    }
                } catch (error) {
                    console.error('❌ 创建角色响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('创建角色', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.createCharacterWithName(CONFIG.testCharacter.name, resolve);

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('创建角色', false, '请求超时');
                    resolve();
                }
            }, 15000);
        });
    }

    createCharacterWithName(name, resolve) {
        const createData = {
            c: 5,
            d: {
                name: name,
                sex: CONFIG.testCharacter.sex,
                roleType: CONFIG.testCharacter.roleType,
                headIndex: CONFIG.testCharacter.headIndex
            }
        };

        console.log(`📤 发送创建角色请求:`, JSON.stringify(createData, null, 2));
        this.ws.send(JSON.stringify(createData));
    }

    async testSelectCharacter() {
        console.log('\n🎯 步骤5: 选择角色...');
        if (this.characters.length === 0) {
            console.log('⚠️ 没有可选择的角色');
            this.addTestResult('选择角色', false, '没有可用角色');
            return;
        }

        return new Promise((resolve) => {
            if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
                this.addTestResult('选择角色', false, 'WebSocket未连接');
                resolve();
                return;
            }

            const targetCharacter = this.characters[0];
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 4) {
                        this.ws.removeListener('message', responseHandler);

                        if (message.code === 0) {
                            this.selectedCharacter = targetCharacter;
                            console.log(`✅ 角色选择成功: ${targetCharacter.name} (ID: ${targetCharacter.id})`);
                            this.addTestResult('选择角色', true, `选择角色: ${targetCharacter.name}`);
                            setTimeout(() => resolve(), 2000);
                        } else {
                            console.log(`❌ 角色选择失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('选择角色', false, message.msg || '选择失败');
                            resolve();
                        }
                    }
                } catch (error) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('选择角色', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({
                c: 4,
                d: { characterId: targetCharacter.id }
            }));

            setTimeout(() => {
                this.ws.removeListener('message', responseHandler);
                this.addTestResult('选择角色', false, '请求超时');
                resolve();
            }, 10000);
        });
    }

    async testQueryGemInventory() {
        console.log('\n💎 步骤6: 查询宝石背包(6034)...');
        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.addTestResult('查询宝石背包', false, 'WebSocket未连接');
            return;
        }

        return new Promise((resolve) => {
            let responseReceived = false;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 6034) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0 && message.list) {
                            this.gemInventory = message.list;
                            console.log('✅ 宝石背包查询成功');
                            console.log(`💎 宝石数量: ${message.list.length}`);
                            console.log(`📋 当前页宝石: ${message.list.length}个`);

                            // 验证宝石数据结构
                            if (message.list.length > 0) {
                                const firstGem = message.list[0];
                                const requiredFields = ['id', 'lvl', 'name', 'num', 'type'];
                                const hasAllFields = requiredFields.every(field => firstGem.hasOwnProperty(field));

                                if (hasAllFields) {
                                    console.log('✅ 宝石数据结构验证通过');
                                    this.addTestResult('宝石背包查询', true, `获取${message.list.length}个宝石，数据结构正确`);

                                    // 显示宝石列表
                                    console.log('📋 宝石列表:');
                                    message.list.forEach((gem, index) => {
                                        console.log(`  ${index + 1}. ${gem.name} (等级${gem.lvl}, 类型${gem.type})`);
                                    });
                                } else {
                                    console.log('❌ 宝石数据结构验证失败');
                                    this.addTestResult('宝石背包查询', false, '宝石数据结构不完整');
                                }
                            } else {
                                console.log('⚠️ 宝石背包为空');
                                this.addTestResult('宝石背包查询', true, '宝石背包为空');
                            }
                        } else {
                            console.log(`❌ 宝石背包查询失败: ${message.msg || '未知错误'}`);
                            this.addTestResult('宝石背包查询', false, message.msg || '查询失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 宝石背包查询响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('宝石背包查询', false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 6034, d: { pageNum: 0 } }));

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult('宝石背包查询', false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    async testGemSocketLogic() {
        console.log('\n⚡ 步骤7: 测试宝石镶嵌逻辑...');

        if (this.gemInventory.length === 0) {
            console.log('⚠️ 宝石背包为空，无法测试镶嵌逻辑');
            this.addTestResult('宝石镶嵌逻辑测试', false, '宝石背包为空');
            return;
        }

        // 测试前几个宝石的镶嵌逻辑
        const testGems = this.gemInventory.slice(0, Math.min(3, this.gemInventory.length));

        for (let i = 0; i < testGems.length; i++) {
            const gem = testGems[i];
            console.log(`\n🔍 测试宝石 ${i + 1}: ${gem.name} (ID: ${gem.id})`);

            // 步骤1: 查询可镶嵌装备 (1090)
            await this.testQuerySocketableEquipment(gem.id, gem.name);
            await this.delay(1000);

            // 步骤2: 如果有可镶嵌装备，测试镶嵌 (1092)
            if (this.socketableEquipments.length > 0) {
                const equipment = this.socketableEquipments[0];
                console.log(`🔧 测试镶嵌到装备: ${equipment.name} (ID: ${equipment.id})`);
                await this.testSocketGem(gem.id, equipment.id, gem.name, equipment.name);
                await this.delay(1000);
            } else {
                console.log('⚠️ 该宝石没有可镶嵌的装备');
            }
        }
    }

    async testQuerySocketableEquipment(gemId, gemName) {
        console.log(`🔍 查询宝石 ${gemName} 的可镶嵌装备(1090)...`);

        return new Promise((resolve) => {
            if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
                this.addTestResult(`1090查询(${gemName})`, false, 'WebSocket未连接');
                resolve();
                return;
            }

            let responseReceived = false;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 1090) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0 && message.data) {
                            this.socketableEquipments = message.data;
                            console.log('✅ 1090接口调用成功');
                            console.log(`🔧 可镶嵌装备数量: ${message.data.length}`);

                            // 验证装备数据结构
                            if (message.data.length > 0) {
                                const firstEquipment = message.data[0];
                                const requiredFields = ['id', 'name', 'stoneStr'];
                                const hasAllFields = requiredFields.every(field => firstEquipment.hasOwnProperty(field));

                                if (hasAllFields) {
                                    console.log('✅ 可镶嵌装备数据结构验证通过');
                                    this.addTestResult(`1090查询(${gemName})`, true, `找到${message.data.length}件可镶嵌装备`);

                                    // 显示装备列表
                                    console.log('🔧 可镶嵌装备列表:');
                                    message.data.forEach((equipment, index) => {
                                        console.log(`  ${index + 1}. ${equipment.name} (ID:${equipment.id}) ${equipment.stoneStr}`);
                                    });
                                } else {
                                    console.log('❌ 可镶嵌装备数据结构验证失败');
                                    this.addTestResult(`1090查询(${gemName})`, false, '装备数据结构不完整');
                                }
                            } else {
                                console.log('⚠️ 该宝石没有可镶嵌的装备');
                                this.addTestResult(`1090查询(${gemName})`, true, '该宝石没有可镶嵌装备');
                            }
                        } else {
                            console.log(`❌ 1090接口调用失败: ${message.msg || '未知错误'}`);
                            this.addTestResult(`1090查询(${gemName})`, false, message.msg || '查询失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 1090接口响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1090查询(${gemName})`, false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 1090, d: { id: gemId } }));

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1090查询(${gemName})`, false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    async testSocketGem(gemId, equipmentId, gemName, equipmentName) {
        console.log(`⚡ 测试宝石镶嵌(1092): ${gemName} → ${equipmentName}...`);

        return new Promise((resolve) => {
            if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
                this.addTestResult(`1092镶嵌(${gemName})`, false, 'WebSocket未连接');
                resolve();
                return;
            }

            let responseReceived = false;

            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 1092) {
                        this.ws.removeListener('message', responseHandler);
                        responseReceived = true;

                        if (message.code === 0) {
                            console.log('✅ 1092接口调用成功');
                            console.log(`📝 镶嵌结果: ${message.msg || message.data}`);
                            this.addTestResult(`1092镶嵌(${gemName})`, true, `镶嵌成功: ${message.msg || message.data}`);
                        } else {
                            console.log(`❌ 1092接口调用失败: ${message.msg || '未知错误'}`);
                            this.addTestResult(`1092镶嵌(${gemName})`, false, message.msg || '镶嵌失败');
                        }
                        resolve();
                    }
                } catch (error) {
                    console.error('❌ 1092接口响应解析失败:', error.message);
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1092镶嵌(${gemName})`, false, '响应解析失败');
                    resolve();
                }
            };

            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 1092, d: { id: gemId, aid: equipmentId } }));

            setTimeout(() => {
                if (!responseReceived) {
                    this.ws.removeListener('message', responseHandler);
                    this.addTestResult(`1092镶嵌(${gemName})`, false, '请求超时');
                    resolve();
                }
            }, 10000);
        });
    }

    async testDisconnect() {
        console.log('\n🔌 步骤8: 断开WebSocket连接...');
        if (this.ws) {
            this.ws.close();
        }
        this.addTestResult('断开连接', true, '连接已断开');
    }

    addTestResult(testName, success, message) {
        this.testResults.push({
            test: testName,
            success: success,
            message: message,
            timestamp: new Date().toISOString()
        });
    }

    printTestResults() {
        console.log('\n📊 测试结果汇总:');
        console.log('='.repeat(50));

        let successCount = 0;
        let totalCount = this.testResults.length;

        this.testResults.forEach((result, index) => {
            const status = result.success ? '✅' : '❌';
            console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
            if (result.success) successCount++;
        });

        console.log('='.repeat(50));
        console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

        if (successCount === totalCount) {
            console.log('🎉 所有测试通过！宝石镶嵌1092指令逻辑正常！');
        } else {
            console.log('⚠️  部分测试失败，请检查日志');
        }

        // 宝石镶嵌结果分析
        if (this.socketResults && this.socketResults.length > 0) {
            console.log('\n⚡ 宝石镶嵌结果分析:');
            console.log('='.repeat(50));
            console.log(`总镶嵌次数: ${this.socketResults.length}`);

            const successSockets = this.socketResults.filter(r => r.code === 0);
            const failedSockets = this.socketResults.filter(r => r.code !== 0);

            console.log(`成功镶嵌: ${successSockets.length}次`);
            console.log(`失败镶嵌: ${failedSockets.length}次`);

            if (successSockets.length > 0) {
                console.log('\n✅ 成功镶嵌详情:');
                successSockets.forEach((socket, index) => {
                    console.log(`  ${index + 1}. ${socket.msg} (${socket.timestamp})`);
                });
            }

            if (failedSockets.length > 0) {
                console.log('\n❌ 失败镶嵌详情:');
                failedSockets.forEach((socket, index) => {
                    console.log(`  ${index + 1}. ${socket.msg} (${socket.timestamp})`);
                });
            }
        }

        // 宝石背包数据结构分析
        if (this.gemInventory && this.gemInventory.length > 0) {
            console.log('\n💎 宝石背包数据结构分析:');
            console.log('='.repeat(50));
            console.log(`总宝石数: ${this.gemInventory.length}`);
            const firstGem = this.gemInventory[0];
            console.log('示例宝石字段:');
            Object.keys(firstGem).forEach(key => {
                console.log(`  ${key}: ${firstGem[key]} (${typeof firstGem[key]})`);
            });
        }

        // 可镶嵌装备数据结构分析
        if (this.socketableEquipments && this.socketableEquipments.length > 0) {
            console.log('\n🔧 可镶嵌装备数据结构分析:');
            console.log('='.repeat(50));
            console.log(`总装备数: ${this.socketableEquipments.length}`);
            const firstEquipment = this.socketableEquipments[0];
            console.log('示例装备字段:');
            Object.keys(firstEquipment).forEach(key => {
                console.log(`  ${key}: ${firstEquipment[key]} (${typeof firstEquipment[key]})`);
            });
        }
    }

    async makeHttpRequest(path, method = 'GET', data = null) {
        return new Promise((resolve, reject) => {
            const options = {
                hostname: CONFIG.server.host,
                port: CONFIG.server.port,
                path: path,
                method: method,
                headers: {
                    'Content-Type': 'application/json',
                }
            };

            if (data) {
                const postData = JSON.stringify(data);
                options.headers['Content-Length'] = Buffer.byteLength(postData);
            }

            const req = http.request(options, res => {
                let body = '';
                res.on('data', (chunk) => { body += chunk; });
                res.on('end', () => {
                    try {
                        const responseData = JSON.parse(body);
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(responseData);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${responseData.message || body}`));
                        }
                    } catch (error) {
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(body);
                        } else {
                            reject(new Error(`HTTP ${res.statusCode}: ${body}`));
                        }
                    }
                });
            });

            req.on('error', (error) => { reject(error); });
            if (data) { req.write(JSON.stringify(data)); }
            req.end();
        });
    }

    async delay(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

async function main() {
    const tester = new GemSocket1092Tester();
    await tester.runTest();
}

if (require.main === module) {
    main().catch((error) => {
        console.error('💥 测试脚本执行失败:', error.message);
        process.exit(1);
    });
}

module.exports = GemSocket1092Tester;
